<?php

/**
 * Entry Name: ec_service_goods
 * LastModified: 2018/3/6 11:12
 * Author: ityong
 * 数据库操作基类
 */
abstract class Model
{
    // 用于保存多个实例
    protected static $instances = [];

    public $dbh = null;

    protected  $tableName = '';

    protected  $primaryKey = 'sysno';


    public function __construct() {}

    final protected function __clone() {}

    /**
     * 单例模式返回操作类
     * @return mixed
     * @throws Yaf_Exception
     * @return self::$instances[$className]
     */
    private static function getInstance()
    {
        $className = static::getClassName();

        // 以前写这个地方的时候，都是判断是否为null，现在改为根据类型判断，更加严谨
        if (!(self::$instances[$className] instanceof  $className)) {
            self::$instances[$className] = new $className();

            //设置表名字 和主键
            if (self::$instances[$className]->tableName == '') {
                self::$instances[$className]->tableName = strtolower(
                    preg_replace('/([a-z])([A-Z])/', "$1" . '_' . "$2", str_replace('Model','',$className))
                );
            }

            if (!Yaf_Registry:: get("mysql") instanceof MySQL) {
                //数据库连接
                $dbConfig = Yaf_Registry::get("config")->get('db');
                Yaf_Registry::set("mysql", new MySQL(
                    $dbConfig->host,
                    $dbConfig->username,
                    $dbConfig->password,
                    $dbConfig->default,
                    $dbConfig->port,
                    $dbConfig->charset
                ));
            }
            self::$instances[$className]->dbh = Yaf_Registry:: get("mysql");
        }

        return self::$instances[$className];
    }

    /**
     * 移除单利操作类
     */
    public static function removeInstance()
    {
        $className = static::getClassName();
        if (array_key_exists($className, self::$instances)) {
            unset(self::$instances[$className]);
        }
    }

    /**
     * 此处返回需要生成实例的类全路径，包括命名空间
     *  - 如果需要创建其他类为单例，此处返回其他类的全命名空间
     *  - 如果是让继承的类成为单例，此方法不需要重写
     */
    protected static function getClassName()
    {
        return get_called_class();
    }

    /**
     * 获取单条数据（主键）
     * @param $id
     * @param string/array  $field
     * @return mixed
     */
    public function getOneById($id,$field = '*'){
        $_this = self::getInstance();
        return $_this->dbh->getRow($_this->tableName,$field, $_this->primaryKey . '=' . $id);
    }


    /**
     * 获取单条数据（条件）
     * @param $where
     * @param string $field
     * @return mixed
     */
    public function getOneByWhere($where,$field = '*'){
        $_this = self::getInstance();
        return $_this->dbh->getRow($_this->tableName,$field, $where);
    }


    /**
     * 查询多条数据
     * @param $where
     * @param $field
     * @return mixed
     */
    public function select($where,$field = '*'){
        //$table,$col = '*',$condition = 1
        $_this = self::getInstance();

        return $_this->dbh->getRows($_this->tableName,$field,$where);
    }


    /**
     * 查询多条数据 带分页
     * @param $pageData
     * @return mixed
     */
    public function selectPage($pageData){

        $_this = self::getInstance();
        $pageArr = [
            'where' => isset($pageData['where']) ? $pageData['where'] : false,
            'pageNo' => isset($pageData['pageNo']) ? $pageData['pageNo'] : 1,
            'showNum' => isset($pageData['showNum']) ? $pageData['showNum'] : 15,
            'field' => isset($pageData['field']) ? (is_array($pageData['field']) ? implode(',',$pageData['field']) : $pageData['field']) : '*',
            'orderBy' => isset($pageData['orderBy']) ? $pageData['orderBy'] : false,
            'groupBy' => isset($pageData['groupBy']) ? $pageData['groupBy'] : false,
        ];

        $sql = 'SELECT ' . $pageArr['field'] . ' FROM ' . $_this->tableName;

        if ($pageArr['where']) {
            $sql .= ' WHERE ' . $pageArr['where'];
        }
        if ($pageArr['groupBy']) {
            $sql .= ' GROUP BY ' . $pageArr['groupBy'];
        }

        if ($pageArr['orderBy']) {
            $sql .= ' ORDER BY ' . $pageArr['orderBy'];
        }

        $startIndex = intval(($pageArr['pageNo'] - 1) * $pageArr['showNum']);

        $sql .= ' LIMIT ' . $startIndex . ',' . $pageArr['showNum'];


        return $_this->dbh->query($sql);

    }

    /**
     * 插入数据
     * @param $data
     * @return mixed
     */
    public function insert($data){
        $_this = self::getInstance();
        return $_this->dbh->add($_this->tableName,$data);
    }

    /**
     * 删除数据
     * @param $where
     * @return mixed
     */
    public function delete($where){
        $_this = self::getInstance();
        return $_this->dbh->delete($_this->tableName,$where);
    }


    /**修改数据
     * @param $data array 跟新的数组
     * @param $where string 更新条件
     * @return mixed
     * @throws
     */
    public function update($data,$where){
        $_this = self::getInstance();
        return $_this->dbh->update($_this->tableName,$data,$where);
    }


    /**
     * 统计数量
     * @param $where
     * @return mixed
     */
    public function count($where){
        $_this = self::getInstance();
        return $_this->dbh->getCounts($_this->tableName,$where);
    }


    /**
     * 执行sql语句 返回受影响行数
     * @param $sql
     * @return int
     */
    public function exec($sql) {
        $_this = self::getInstance();
        return $_this->dbh->exec($sql);

    }


    /**
     * 执行sql语句 返回结果集合
     * @param $sql
     * @return array
     */
    public function query($sql) {
         return self::getInstance()->dbh->query($sql);
    }

    /**
     * 开启事务
     * @return bool
     */
    public function begin() {
        return self::getInstance()->dbh->begin();
    }

    /**
     * 事务回滚
     * @return bool
     */
    public function rollback() {
        return self::getInstance()->dbh->rollback();
    }

    /**
     * 事务提交
     * @return bool
     */
    public function commit() {
        return self::getInstance()->dbh->commit();
    }


    /**
     * 获取run
     * @return this
     */
    public function run() {
        return self::getInstance();
    }

    /**
     * 获取pdo对象
     * @return PDO
     */
    public function getPdo() {
        return self::getInstance()->dbh->pdo;
    }

    /**
     * 获取执行sql
     * @return string
     */
    public function getSql() {
        return self::getInstance()->dbh->getSql();
    }


}